Skip to main content
  1. SwiftUI in 100 Days Notes/

Day 56 - SwiftUI Project-11 (BookWorm) Challange and Solutions

Table of Contents

Congratulations on finishing another SwiftUI project! With technologies like SwiftData on your side, you can now build some serious apps that interact with the user and most importantly remember what they input. While we’ve only had one introduction to SwiftData, it can do so much more, and I expect Apple to continue to expand the connection between SwiftData and SwiftUI in future updates. In the meantime, the next project focuses on SwiftData in depth.

Challange #

  1. Currently it is possible to leave title, author and genre unset when saving a book, which causes a problem for detail view. Please fix this by forcing defaults, validating the form or showing a default image for unknown genres, the choice is yours.
  2. Modify the ContentView so that books rated 1 star are highlighted in some way, for example by showing their name in red.
  3. Add a new “date” attribute to the Book class, assign Date.now to get the current date and time, then format it nicely somewhere in the DetailView.

Solutions #

  1. The way I have chosen to solve this step is that if the fields consist of whitespaces, we will not allow to press the save button. For this we will write a String extension in AddBookView and check if the String consists of whitespaces. Add the following code for this;

    extension String {
        var isBlank: Bool {
            allSatisfy({$0.isWhitespace})
        }
    }
    

    Then we will add a computed variable and check that all fields meet our conditions.

    var isAllAreaValid: Bool {
        if title.isBlank || author.isBlank || rating<1 || review.isBlank {
            return false
        }
    
        return true
    
    }
    

    Finally, change Section-3 in AddBookView Form as follows;

                    Section {
                        Button("Save") {
                            let newBook = Book(title: title, author: author, genre: genre, review: review, rating: rating)
                            modelContext.insert(newBook)
                            dismiss()
                        } //Button
                        .disabled(isAllAreaValid == false)
                    } //Section-3
    

    Challange-1 Solution Github

  2. To solve this problem, we will add the following modifier to the Text view in the ContentView where we write the name of the book. In this way, if 1 star is given, the book name will be in red colour, otherwise we will leave it in default colour.

    Text(book.title)
                .font(.headline)
          .foregroundStyle(book.rating == 1 ? .red : .primary)
    

    Challange-2 Solution Github

  3. To solve this problem, let’s first add a new attribute to the Book class and give its default value;

     var date = Date.now
    

    Then let’s add to the init method of the Book class as follows;

     init(title: String, author: String, genre: String, review: String, rating: Int, date: Date) {
    

    After doing these operations, since we want to get the time when the save button is pressed in AddBookView, let’s change the let newBook part as follows;

    let newBook = Book(title: title, author: author, genre: genre, review: review, rating: rating, date: Date.now)
    

    Finally, in DetailView, we want to show the date on the image as follows

    BookWorm DetailView Date Time

    For this, let’s change the ZStack section as follows;

    ZStack(alignment: .bottom) {
        Image(book.genre)
            .resizable()
            .scaledToFit()
        HStack() {
    
            Text(book.date, format: .dateTime)
                .font(.caption)
                .fontWeight(.black)
                .padding(8)
                .foregroundStyle(.white)
                .background(.black.opacity(0.75))
                .clipShape(.capsule)
                .offset(x: +5, y: -5)
    
            Spacer()
    
            Text(book.genre.uppercased())
                .font(.caption)
                .fontWeight(.black)
                .padding(8)
                .foregroundStyle(.white)
                .background(.black.opacity(0.75))
                .clipShape(.capsule)
                .offset(x: -5, y: -5)
    
    
        }
    
    } //ZStack
    

    Also, let’s make a small change in the code so that the preview code in DetailView is not broken;

     let example = Book(title: "Test Book", author: "Test Author", genre: "Fantasy", review: "This was a great book; I really enjoyed it.", rating: 4, date: Date.now)
    

    Challange-3 Solution Github


You can also read this article in Turkish.
Bu yazıyı Türkçe olarak da okuyabilirsiniz.

This article contains the notes I took for myself from the articles found at SwiftUI Day 56. Please use the link to follow the original lesson.